package com.handy.easy.admin.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.handy.easy.admin.constants.BaseConstants;
import com.handy.easy.admin.constants.enums.LoginSourceEnum;
import com.handy.easy.admin.constants.enums.ResultEnum;
import com.handy.easy.admin.dto.SimpleRegisterDto;
import com.handy.easy.admin.dto.users.SysUserAddDto;
import com.handy.easy.admin.dto.users.SysUserDto;
import com.handy.easy.admin.dto.users.SysUserEditDto;
import com.handy.easy.admin.dto.users.SysUserLockDto;
import com.handy.easy.admin.mapper.SysUserAccountMapper;
import com.handy.easy.admin.mapper.SysUserMapper;
import com.handy.easy.admin.model.sys.SysUser;
import com.handy.easy.admin.model.sys.SysUserAccount;
import com.handy.easy.admin.service.SysRoleService;
import com.handy.easy.admin.service.SysUserService;
import com.handy.easy.admin.util.AssertUtil;
import com.handy.easy.admin.vo.PageVo;
import com.handy.easy.admin.vo.ResultVo;
import com.handy.easy.admin.vo.admin.users.SysUserVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户
 *
 * @author handy
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private final SysUserAccountMapper sysUserAccountMapper;
    private final SysRoleService sysRoleService;

    /**
     * 用户密码注册
     *
     * @param simpleRegisterDto 入参
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<Boolean> simpleRegister(SimpleRegisterDto simpleRegisterDto) {
        SysUserAccount sysAccount = sysUserAccountMapper.selectOne(Wrappers.lambdaQuery(new SysUserAccount())
                .eq(SysUserAccount::getSource, LoginSourceEnum.ACCOUNT)
                .eq(SysUserAccount::getUsername, simpleRegisterDto.getUsername())
                .last("limit 1"));
        // 校验
        AssertUtil.isNotNull(sysAccount, ResultEnum.REGISTER_DUPLICATE_NAME);
        AssertUtil.isNotTrue(simpleRegisterDto.getPassword().equals(simpleRegisterDto.getTwoPassword()), ResultEnum.REGISTER_DUPLICATE_PASSWORD);
        // 新增用户
        SysUser sysUser = new SysUser();
        sysUser.setCode(IdUtil.getSnowflake(1, 1).nextIdStr());
        sysUser.setName(simpleRegisterDto.getUsername());
        sysUser.setLockFlag(BaseConstants.NOT_DELETE_FLAG);
        boolean rst = this.save(sysUser);
        AssertUtil.isNotTrue(rst);
        // 新增用户帐号
        SysUserAccount account = new SysUserAccount();
        account.setUserId(sysUser.getId());
        account.setSource(LoginSourceEnum.ACCOUNT.getSource());
        account.setUsername(simpleRegisterDto.getUsername());
        account.setPassword(SaSecureUtil.md5BySalt(simpleRegisterDto.getPassword(), BaseConstants.SALT));
        rst = sysUserAccountMapper.insert(account) > 0;
        AssertUtil.isNotTrue(rst);
        return ResultVo.success(true);
    }

    /**
     * 分页查询用户列表
     *
     * @param sysUserDto 入参
     * @return SysUserVo
     */
    @Override
    public PageVo<SysUserVo> page(SysUserDto sysUserDto) {
        LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery(new SysUser())
                .eq(StrUtil.isNotBlank(sysUserDto.getCode()), SysUser::getCode, sysUserDto.getCode())
                .like(StrUtil.isNotBlank(sysUserDto.getName()), SysUser::getName, "%" + sysUserDto.getName() + "%")
                .orderByDesc(SysUser::getId);
        IPage<SysUser> sysAccountPage = this.page(new Page<>(sysUserDto.getPage(), sysUserDto.getLimit()), wrapper);
        List<SysUserVo> sysUserVos = BeanUtil.copyToList(sysAccountPage.getRecords(), SysUserVo.class);
        for (SysUserVo sysUserVo : sysUserVos) {
            if (sysUserVo.getSex() != null) {
                sysUserVo.setSexStr(sysUserVo.getSex() == 1 ? "男" : "女");
            }
        }
        return PageVo.create(sysUserVos, sysAccountPage.getTotal());
    }

    /**
     * 用户详情
     *
     * @param id userId
     * @return SysUserVo
     */
    @Override
    public SysUserVo view(Long id) {
        return BeanUtil.copyProperties(this.getById(id), SysUserVo.class);
    }

    /**
     * 锁定
     *
     * @param sysUserLockDto 入参
     * @return true
     */
    @Override
    public boolean lock(SysUserLockDto sysUserLockDto) {
        SysUser sysUser = this.getById(sysUserLockDto.getId());
        AssertUtil.isNull(sysUser, ResultEnum.NOT_DATA_FAILURE);
        sysUser.setLockFlag(sysUserLockDto.getLockFlag());
        return this.updateById(sysUser);
    }

    /**
     * 新增
     *
     * @param sysUserAddDto 入参
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(SysUserAddDto sysUserAddDto) {
        SysUserAccount sysAccount = sysUserAccountMapper.selectOne(Wrappers.lambdaQuery(new SysUserAccount())
                .eq(SysUserAccount::getSource, LoginSourceEnum.ACCOUNT)
                .eq(SysUserAccount::getUsername, sysUserAddDto.getName())
                .last("limit 1"));
        // 校验
        AssertUtil.isNotNull(sysAccount, ResultEnum.REGISTER_DUPLICATE_NAME);
        // 新增用户
        SysUser sysUser = new SysUser();
        sysUser.setCode(IdUtil.getSnowflake(1, 1).nextIdStr());
        sysUser.setName(sysUserAddDto.getName());
        sysUser.setLockFlag(BaseConstants.NOT_DELETE_FLAG);
        sysUser.setSex(sysUserAddDto.getSex());
        sysUser.setEmail(sysUserAddDto.getEmail());
        sysUser.setBirthData(sysUserAddDto.getBirthData());
        sysUser.setNote(sysUserAddDto.getNote());
        boolean rst = this.save(sysUser);
        AssertUtil.isNotTrue(rst);
        // 新增用户帐号
        SysUserAccount account = new SysUserAccount();
        account.setUserId(sysUser.getId());
        account.setSource(LoginSourceEnum.ACCOUNT.getSource());
        account.setUsername(sysUserAddDto.getName());
        account.setPassword(SaSecureUtil.md5BySalt(sysUserAddDto.getPassword(), BaseConstants.SALT));
        rst = sysUserAccountMapper.insert(account) > 0;
        AssertUtil.isNotTrue(rst);
        // 如果有邮箱增加邮箱登录
        if (StrUtil.isNotBlank(sysUserAddDto.getEmail())) {
            SysUserAccount emailAccount = new SysUserAccount();
            emailAccount.setUserId(sysUser.getId());
            emailAccount.setSource(LoginSourceEnum.EMAIL.getSource());
            emailAccount.setEmail(sysUserAddDto.getEmail());
            emailAccount.setPassword(SaSecureUtil.md5BySalt(sysUserAddDto.getPassword(), BaseConstants.SALT));
            rst = sysUserAccountMapper.insert(emailAccount) > 0;
            AssertUtil.isNotTrue(rst);
        }
        return true;
    }

    /**
     * 编辑
     *
     * @param sysUserEditDto 入参
     * @return true
     */
    @Override
    public boolean edit(SysUserEditDto sysUserEditDto) {
        SysUser sysUser = this.getById(sysUserEditDto.getId());
        AssertUtil.isNull(sysUser, ResultEnum.NOT_DATA_FAILURE);
        sysUser.setName(sysUserEditDto.getName());
        sysUser.setSex(sysUserEditDto.getSex());
        sysUser.setBirthData(sysUserEditDto.getBirthData());
        sysUser.setEmail(sysUserEditDto.getEmail());
        sysUser.setNote(sysUserEditDto.getNote());
        return this.updateById(sysUser);
    }

    /**
     * 删除
     *
     * @param ids 入参
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        this.removeByIds(ids);
        sysUserAccountMapper.delete(Wrappers.lambdaQuery(new SysUserAccount()).in(SysUserAccount::getUserId, ids));
        sysRoleService.delByUserIds(ids);
    }

}